面试题:为什么使用 Bundle 而不使用 HashMap
The following article is from ByteCode Author 程序员DHL
本文作者
作者:程序员DHL
链接:
https://juejin.cn/post/7408379631093219379
本文由作者授权发布。
Bundle 内部是由 ArrayMap 实现的,ArrayMap 和 HashMap 是 Android 中常用的两种键值对数据结构,关于它们的区别可以前往微信小程序「猿面试」中查看 「ArrayMap和HashMap的区别」。
Bundle 内部是由 ArrayMap 实现的,ArrayMap 的内部实现是两个数组,一个记录所有 key 的 hashcode 值组成的数组,是从小到大的排序方式,一个存放 key-value。
内部使用二分法进行查找,时间复杂度为 O (log n),但由于数组操作(如插入、删除)需要移动元素,插入和删除的时间复杂度为 O (n),因此只适合于小数据量操作。
ArrayMap 满足条件会扩容后的大小为原来的 1.5 倍,并且有容量收缩机制,当内存使用量不足 1/3 的情况下,内存数组会收紧 50%。
Activity 之间通过 Intent 传递数据,因为其内部使用了 Binder 通信机制。
HashMap 使用 Serializable 进行序列化,而 Bundle 则是使用 Parcelable 进行序列化。
Serializable
Serializable 是 Java 原生序列化的方式,主要通过 ObjectInputStream 和 ObjectOutputStream 来实现对象序列化和反序列化。
在整个过程中用到了大量的反射和临时变量,会频繁的触发 GC,序列化的性能会非常差。
序列化时需要手动指定 serialVersionUID,用来辅助序列化和反序列化过程的,序列化与反序列化的 serialVersionUID 必须相同才能够使序列化操作成功,如果不显式声明 serialVersionUID,类的任何细节改变,都可能改变默认的 serialVersionUID 这可能导致反序列化失败。
Parcelable
Parcelable 是为了解决了在 Android 中跨进程通信性能差的问题,Parcelable 写入和读取的时候都是采用自定义序列化存储的方式,不需要使用反射来推断它,因此 Parcelable 比 Serializable要快很多。
Serializable 的设计初衷是为了序列化对象到本地文件、数据库、网络流、RMI 以便数据传输,当然这种传输可以是程序内的也可以是两个程序间的。
而 Android 的 Parcelable 的设计初衷是由于 Serializable 效率过低,消耗大,而 Android 中数据传递主要是在内存环境中(内存属于 Android 中的稀有资源),因此 Parcelable 的出现为了满足数据在内存中低开销而且高效地传递问题。
因此 Android 应用程序在内存间数据传输时推荐使用 Parcelable。
如果数据持久化存储,推荐使用 Serializable 更加方便,因为 Parcelables 与数据存储一起使用是不安全的,因为数据格式可能会在 Android 版本之间改变。因此在序列化到存储设备或者网络传输方面还是尽量选择 Serializable 接口。
最后推荐一下我做的网站,玩Android: wanandroid.com ,包含详尽的知识体系、好用的工具,还有本公众号文章合集,欢迎体验和收藏!
扫一扫 关注我的公众号
如果你想要跟大家分享你的文章,欢迎投稿~
┏(^0^)┛明天见!